using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.ComponentModel;

namespace Lizk.SimpleHUD
{
    [Serializable]
    public abstract class HUDContainer : HUDControl, ICollection, ICollection<HUDControl>
    {
        public override void ResizeMove(RectangleS oldRect, RectangleS newRect)
        {
            foreach (HUDControl control in this)
            {
                RectangleS moveRect = new RectangleS(control.Bounds.X, control.Bounds.Y, control.Bounds.Width, control.Bounds.Height);



                if ((control.Anchor & Anchor.Top) == Anchor.Top && (control.Anchor & Anchor.Bottom) == Anchor.Bottom)
                {
                    moveRect.Height += newRect.Height - oldRect.Height;
                    if (control.DestinationSize != PointS.Empty)
                        control.DestinationSize = new PointS(control.DestinationSize.X, control.DestinationSize.Y + newRect.Height - oldRect.Height);

                }
                else if ((control.Anchor & Anchor.Bottom) == Anchor.Bottom)
                {
                    moveRect.Y += newRect.Height - oldRect.Height;
                    if (control.Destination != PointS.Empty)
                        control.Destination = new PointS(control.Destination.X, control.Destination.Y + newRect.Height - oldRect.Height);
                }

                if ((control.Anchor & Anchor.Left) == Anchor.Left && (control.Anchor & Anchor.Right) == Anchor.Right)
                {
                    moveRect.Width += newRect.Width - oldRect.Width;
                    if (control.DestinationSize != PointS.Empty)
                        control.DestinationSize = new PointS(control.DestinationSize.X + newRect.Width - oldRect.Width, control.DestinationSize.Y);
                }
                else if ((control.Anchor & Anchor.Right) == Anchor.Right)
                {
                    moveRect.X += newRect.Width - oldRect.Width;
                    if (control.Destination != PointS.Empty)
                        control.Destination = new PointS(control.Destination.X + newRect.Width - oldRect.Width, control.Destination.Y);
                }
                control.Bounds = moveRect;
                /*
                 * if bottom and top
                 *  adjust height
                 * if bottom
                 *   move height difference
                 * 
                 * if top 
                 * 
                 * if not top
                 *   adjust top 
                 * 
                 * 
                 * 
                 */
            }
            
            base.ResizeMove(oldRect, newRect);
        }
        

        public override void Update(TimeSpan ts)
        {
            base.Update(ts);
            foreach (HUDControl control in this)
            {
                control.Update(ts);
            }
        }

        public abstract IEnumerator<HUDControl> GetEnumerator();
        public abstract void Add(HUDControl item);
        public abstract void AddRange(params HUDControl[] items);
        public abstract void AddRange(ICollection<HUDControl> items);
        public abstract void Clear();
        public abstract bool Contains(HUDControl item);
        public abstract void CopyTo(HUDControl[] array, int arrayIndex);
#if !XBOX
        [Browsable(false)]
#endif
        public abstract int Count { get; }
        public abstract T Get<T>(int index) where T : HUDControl;
#if !XBOX
        [Browsable(false)]
#endif
        public bool IsReadOnly { get {  return false; } }
        public abstract bool Remove(HUDControl item);
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #region ICollection Members

        public void CopyTo(Array array, int index)
        {
            CopyTo((HUDControl[])array, index);
        }

#if !XBOX
        [Browsable(false)]
#endif
        public bool IsSynchronized
        {
            get { return true; }
        }

#if !XBOX
        [Browsable(false)]
#endif
        public object SyncRoot
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        #endregion
    }


    [Serializable]
    public class HUDContainerSimple : HUDContainer, IList<HUDControl>
    {
        protected List<HUDControl> controls = new List<HUDControl>();

        public override IEnumerator<HUDControl> GetEnumerator()
        {
            return controls.GetEnumerator();
        }

        public override void Add(HUDControl item)
        {
            controls.Add(item);
            item.Parent = this;
        }

        public override void AddRange(ICollection<HUDControl> items)
        {
            controls.AddRange(items);
            foreach (HUDControl c in items)
                c.Parent = this;
        }

        
        public override void AddRange(params HUDControl[] items)
        {
            controls.AddRange(items);
            foreach (HUDControl c in items)
                c.Parent = this;
        }

        public override void Clear()    
        {
            controls.Clear();
        }

        public override bool Contains(HUDControl item)
        {
            return controls.Contains(item);
        }

        public override void CopyTo(HUDControl[] array, int arrayIndex)
        {
            controls.CopyTo(array, arrayIndex);
        }

#if !XBOX
        [Browsable(false)]
#endif
        public override int Count
        {
            get { return controls.Count; }
        }

        public override bool Remove(HUDControl item)
        {
            return controls.Remove(item);
        }

        public override T Get<T>(int index) 
        {
            return (T)this[index];
        }

        #region IList<HUDControl> Members

        public int IndexOf(HUDControl item)
        {
            return controls.IndexOf(item);
        }

        public void Insert(int index, HUDControl item)
        {
            controls.Insert(index, item);
            item.Parent = this;
        }

        public void RemoveAt(int index)
        {
            controls.RemoveAt(index);
        }

        public HUDControl this[int index]
        {
            get
            {
                return controls[index];
            }
            set
            {
                controls[index] = value;
            }
        }

        #endregion

        public override bool MouseDown(PointS point, MouseButtons buttons)
        {
            Stack<HUDControl> stack = new Stack<HUDControl>(controls);

            base.MouseDown(point, buttons);
            while (stack.Count > 0)
            {
                HUDControl control = stack.Pop();
                
                if (control.Bounds.Contains(point - Location) && control.Visible)
                {
                    if (control.MouseDown(point - Location, buttons))
                        return true;
                }
                
            }
            return false;
        }
        public override bool MouseUp(PointS point, MouseButtons buttons)
        {
            Stack<HUDControl> stack = new Stack<HUDControl>(controls);

            base.MouseUp(point, buttons);
            while (stack.Count > 0)
            {
                HUDControl control = stack.Pop();

                if (control.Bounds.Contains(point - Location) && control.Visible)
                {
                    if (control.MouseUp(point - Location, buttons))
                        return true;
                }

            }
            return false;
        }

        public override void UpdateMousePosition(PointS position)
        {
            foreach (HUDControl c in this)
                c.UpdateMousePosition(position - this.Location);
            base.UpdateMousePosition(position);
        }

    }
}
